package volatileStudy;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 该共享资源不可见
 */
class UnSeeData{
    int num = 0;

    public int setAndGet(){
        this.num = 30;
        return this.num;
    }
}

class SeeData{
    volatile int num = 0;

    public int setAndGet(){
        this.num = 30;
        return this.num;
    }
}

/**
 *
 */
class AddClass{
    volatile int num;
    void numPlusPlus(){
        num++;
    }
    //解决操作资源的原子性问题
    AtomicInteger atomicInteger = new AtomicInteger();
    void atomicIntegerPlusPlus(){
        atomicInteger.incrementAndGet();
    }
}

class AddClassOperationClass{
    void operation(){
        AddClass addClass = new AddClass();
        for (int i = 1; i <= 10; i++) {
            new Thread(()->{
                for (int j = 1; j <= 100; j++) {
                    addClass.numPlusPlus();
                    addClass.atomicIntegerPlusPlus();
                }
            },String.valueOf(i)).start();
        }
//        while (Thread.activeCount() > 2){
//            Thread.yield();
//        }
        System.out.println("num的最终值:" + addClass.num);
        System.out.println("atomicInteger的最终值:" + addClass.atomicInteger);
    }
}

/**
 * 可见性测试
 */
public class SeeTest {
    /**
     * 不可见测试
     */
    static void unSeeMethod(){
        UnSeeData data = new UnSeeData();

        //进行值得修改
        new Thread(()->{
            System.out.println("修改之前的值:" + data.num);
            try {
                Thread.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //修改操作
            int i = data.setAndGet();
            System.out.println("修改之后的值:" + i);
        }).start();


        //判断修改之后的数值是否会改变-------此时出现程序卡死，主程序不知道主内存的数据发生了改变因此程序一直卡着不懂
        while (data.num == 0){

        }
        System.out.println("主线程读取到修改之后的值了");
    }

    /**
     * 别的线程修改了共享资源的值，其他线程能立马获取到修改之后的值
     */
    static void seeMethod(){
        SeeData data = new SeeData();

        //进行值得修改
        new Thread(()->{
            System.out.println("修改之前的值:" + data.num);
            try {
                Thread.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //修改操作
            int i = data.setAndGet();
            System.out.println("修改之后的值:" + i);
        }).start();

        //判断修改之后的数值是否会改变-------此时出现程序卡死，主程序不知道主内存的数据发生了改变因此程序一直卡着不懂
        while (data.num == 0){

        }
        System.out.println("主线程读取到修改之后的值了");
    }

    public static void main(String[] args) {
//        seeMethod();
        AddClassOperationClass addClassOperationClass = new AddClassOperationClass();
        addClassOperationClass.operation();
    }
}
